
/**
  ******************************************************************************
  * Copyright 2021 The Microbee Authors. All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  * 
  * http://www.apache.org/licenses/LICENSE-2.0
  * 
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  * 
  * @file       sensor_baro_backend.h
  * @author     baiyang
  * @date       2021-11-21
  ******************************************************************************
  */

#pragma once

#ifdef __cplusplus
extern "C"{
#endif

/*----------------------------------include-----------------------------------*/
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>

#include <rtthread.h>
/*-----------------------------------macro------------------------------------*/

/*----------------------------------typedef-----------------------------------*/
/*
  device driver IDs. These are used to fill in the devtype field
  of the device ID, which shows up as BARO_DEVID* parameters to
  users.
 */
enum BaroDevTypes {
    DEVTYPE_BARO_SITL     = 0x01,
    DEVTYPE_BARO_BMP085   = 0x02,
    DEVTYPE_BARO_BMP280   = 0x03,
    DEVTYPE_BARO_BMP388   = 0x04,
    DEVTYPE_BARO_DPS280   = 0x05,
    DEVTYPE_BARO_DPS310   = 0x06,
    DEVTYPE_BARO_FBM320   = 0x07,
    DEVTYPE_BARO_ICM20789 = 0x08,
    DEVTYPE_BARO_KELLERLD = 0x09,
    DEVTYPE_BARO_LPS2XH   = 0x0A,
    DEVTYPE_BARO_MS5611   = 0x0B,
    DEVTYPE_BARO_SPL06    = 0x0C,
    DEVTYPE_BARO_UAVCAN   = 0x0D,
    DEVTYPE_BARO_MSP      = 0x0E,
};

/**
  * @brief       
  * @param[out]  
  * @retval      
  * @note        
  */
typedef struct {
    struct sensor_baro_backend_ops *ops;

    // mutex for access to shared frontend data
    rt_mutex_t _mutex;

    // mean pressure for range filter
    float _mean_pressure;

    // number of dropped samples. Not used for now, but can be usable to choose more reliable sensor
    uint32_t _error_count;
} sensor_baro_backend;

/**
 * sensor baro operators
 */
struct sensor_baro_backend_ops {
    void (*sensor_baro_backend_destructor)(sensor_baro_backend *baro_backend);

    // each driver must provide an update method to copy accumulated
    // data to the frontend
    void (*update)(sensor_baro_backend *baro_backend);
    
    // accumulate function. This is used for backends that don't use a
    // timer, and need to be called regularly by the main code to
    // trigger them to read the sensor
    void (*accumulate)(sensor_baro_backend *baro_backend);

    void (*update_healthy_flag)(sensor_baro_backend *baro_backend, uint8_t instance);
};

/*----------------------------------variable----------------------------------*/
extern struct sensor_baro_backend_ops baro_backend_ops;
/*-------------------------------------os-------------------------------------*/

/*----------------------------------function----------------------------------*/
void sensor_baro_backend_ctor(sensor_baro_backend *baro_backend, char *name);
void sensor_baro_backend_update(sensor_baro_backend *baro_backend, uint8_t instance);
void sensor_baro_backend_copy_to_frontend(uint8_t instance, float pressure, float temperature);
//  Check that the baro valid by using a mean filter.
// If the value further that filtrer_range from mean value, it is rejected.
bool sensor_baro_backend_pressure_ok(sensor_baro_backend *baro_backend, float press);
static inline uint32_t sensor_baro_backend_get_error_count(sensor_baro_backend *baro_backend) { return baro_backend->_error_count; }
void sensor_baro_backend_set_bus_id(uint8_t instance, uint32_t id);

static inline void sensor_baro_backend_mutex_take(sensor_baro_backend *baro_backend) {
    rt_mutex_take(baro_backend->_mutex, RT_WAITING_FOREVER);
}

static inline void sensor_baro_backend_mutex_release(sensor_baro_backend *baro_backend) {
    rt_mutex_release(baro_backend->_mutex);
}

static inline void sensor_baro_backend_destructor(sensor_baro_backend *baro_backend) {
    if (baro_backend->ops->sensor_baro_backend_destructor != NULL) {
        baro_backend->ops->sensor_baro_backend_destructor(baro_backend);
    }
}

static inline void sensor_baro_backend_update2(sensor_baro_backend *baro_backend) {
    if (baro_backend->ops->update != NULL) {
        baro_backend->ops->update(baro_backend);
    }
}

static inline void sensor_baro_backend_accumulate(sensor_baro_backend *baro_backend) {
    if (baro_backend->ops->accumulate != NULL) {
        baro_backend->ops->accumulate(baro_backend);
    }
}

static inline void sensor_baro_backend_update_healthy_flag(sensor_baro_backend *baro_backend, uint8_t instance) {
    if (baro_backend->ops->update_healthy_flag != NULL) {
        baro_backend->ops->update_healthy_flag(baro_backend, instance);
    }
}
/*------------------------------------test------------------------------------*/

#ifdef __cplusplus
}
#endif



